package upload

import (
	"gitee.com/CrazyMage/blog-service/global"
	"gitee.com/CrazyMage/blog-service/pkg/util"
	"io"
	"io/ioutil"
	"mime/multipart"
	"os"
	"path"
	"strings"
)

type FileType int

const TypeImage FileType = iota + 1

func GetFileName(name string) string {
	ext := GetFileExt(name)                   // 获取扩展名（如 ".pdf"）
	fileName := strings.TrimSuffix(name, ext) // 移除扩展名（得到 "document"）
	fileName = util.EncodeMD5(fileName)       // 对主体进行MD5编码

	return fileName + ext
}

// 从文件名中提取扩展名
func GetFileExt(name string) string {
	return path.Ext(name)
}

func GetSavePath() string {
	return global.AppSetting.UploadSavePath
}

func GetServerUrl() string {
	return global.AppSetting.UploadServerUrl
}

func CheckSavePath(dst string) bool {
	_, err := os.Stat(dst) // 获取路径信息

	return os.IsNotExist(err) // 判断路径是否不存在
}

// 这段代码是一个文件扩展名检查函数，用于验证给定的文件名是否属于允许的文件类型（特别是图片类型）
func CheckContainExt(t FileType, name string) bool {
	ext := GetFileExt(name)    // 获取文件扩展名（如".jpg"）
	ext = strings.ToUpper(ext) // 转为大写（如".JPG"）
	switch t {
	case TypeImage: // 当检查图片类型时
		// 遍历允许的图片扩展名列表
		for _, allowExt := range global.AppSetting.UploadImageAllowExts {
			if strings.ToUpper(allowExt) == ext {
				return true
			}
		}

	}

	return false
}

func CheckMaxSize(t FileType, f multipart.File) bool {
	content, _ := ioutil.ReadAll(f) // 读取文件全部内容
	size := len(content)            // 获取文件字节大小
	switch t {
	case TypeImage: // 当检查图片类型时
		if size >= global.AppSetting.UploadImageMaxSize*1024*1024 {
			return true // 超过最大尺寸限制
		}
	}

	return false // 未超过限制
}

func CheckPermission(dst string) bool {
	_, err := os.Stat(dst) // 尝试获取路径信息

	return os.IsPermission(err) // 判断是否权限不足
}

// 这段代码定义了一个用于递归创建目录路径的工具函数
func CreateSavePath(dst string, perm os.FileMode) error {
	err := os.MkdirAll(dst, perm) // 递归创建目录
	if err != nil {
		return err // 返回可能的错误
	}

	return nil // 创建成功
}

func SaveFile(file *multipart.FileHeader, dst string) error {
	src, err := file.Open() // 打开上传文件流
	if err != nil {
		return err
	}
	defer src.Close()

	out, err := os.Create(dst) // 创建目标文件
	if err != nil {
		return err
	}
	defer out.Close() // 确保关闭目标文件

	_, err = io.Copy(out, src)
	return err
}
